import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from statsmodels.tsa.arima.model import ARIMA
import seaborn as sns
import statsmodels.api as sm
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
import plotly.graph_objects as go

# 1. 数据预处理和清洗
# 读取CSV文件
df = pd.read_csv('./data/数据分析/Coffee_Chain_Sales.csv', nrows=20)
features = df[['Date', 'Market','AreaCode', 'Cogs', 'Margin', 'Profit', 'InventoryMargin']]
target = df['Sales']
print(f"{features}")
fig, ax = plt.subplots(figsize=(10, 6))
ax.axis('tight')
ax.axis('off')
# 绘制表格
the_table = ax.table(cellText=features.values, colLabels=features.columns, cellLoc='center', loc='center')
# 设置表格列宽为自适应
for j in range(len(features.columns)):
    the_table.auto_set_column_width(col=j)
# 设置表格属性
the_table.auto_set_font_size(False)
the_table.set_fontsize(10)  # Adjust fontsize as needed
# 应用渐变颜色
num_rows = len(features)
for i in range(num_rows):
    for j in range(len(features.columns)):
        cell = the_table._cells[(i, j)]
plt.legend()
plt.show()

df = pd.read_csv('./data/数据分析/Coffee_Chain_Sales.csv')
# 将Date列转换为datetime格式
df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%Y')
# 提取年份、月份作为新特征
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
features = df[['Year', 'Month', 'AreaCode', 'Cogs', 'Margin', 'Sales', 'InventoryMargin']]
target = df['Profit']
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 将训练集和测试集标签添加到原始DataFrame中，以便于可视化时区分
df['Dataset'] = 'Not Selected'
df.loc[X_train.index, 'Dataset'] = 'Train'
df.loc[X_test.index, 'Dataset'] = 'Test'
# 使用seaborn绘制散点图以展示Cogs和Profit的分布
plt.figure(figsize=(10, 6))
sns.scatterplot(x='Cogs', y='Profit', hue='Dataset', data=df, alpha=0.7)
plt.title('Scatter Plot of Cogs and Profit for Train and Test Sets')
plt.xlabel('Cogs')
plt.ylabel('Profit')
plt.show()
# 绘制Sales的分布图（直方图）
plt.figure(figsize=(10, 6))
sns.histplot(df['Profit'][df['Dataset'] == 'Train'], label='Train', alpha=0.7, bins=30, kde=True)
sns.histplot(df['Profit'][df['Dataset'] == 'Test'], label='Test', alpha=0.7, bins=30, kde=True)
plt.title('Distribution of Profit for Train and Test Sets')
plt.xlabel('Profit')
plt.ylabel('Frequency')
plt.legend()
plt.show()


# 线性回归模型
lr_model = LinearRegression()
lr_model.fit(X_train_scaled, y_train)
lr_predictions = lr_model.predict(X_test_scaled)

# SVR回归模型
svr_model = SVR(kernel='rbf')
svr_model.fit(X_train_scaled, y_train)
svr_predictions = svr_model.predict(X_test_scaled)

# ARIMA时间回归模型
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2,
                                                    shuffle=False)  # shuffle必须为False以保持时间序列的连续性
model = ARIMA(y_train, order=(1, 1, 1))
model_fit = model.fit()
yhat = model_fit.forecast(steps=len(y_test))

# 多元线性回归模型
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(features, target, test_size=0.2, random_state=42)
model_reg = sm.OLS(y_train_reg, X_train_reg).fit()
predictions_reg = model_reg.predict(X_test_reg)

lr_mse = mean_squared_error(y_test, lr_predictions)
svr_mse = mean_squared_error(y_test, svr_predictions)
arima_mse = mean_squared_error(y_test, yhat)
predictions_mse = mean_squared_error(y_test, predictions_reg)
rmse = np.sqrt(lr_mse)
svr_rmse = np.sqrt(svr_mse)
arima_rmse = np.sqrt(arima_mse)
predictions_rmse = np.sqrt(predictions_mse)

print(f"Profit LR MSE: {lr_mse}")
print(f"Profit LR RMSE: {rmse}")
print(f"Profit SVR MSE: {svr_mse}")
print(f"Profit SVR RMSE: {svr_rmse}")
print(f"Profit ARIMA MSE: {arima_mse}")
print(f"Profit ARIMA RMSE: {arima_rmse}")
print(f"Profit PREDICT MSE: {predictions_mse}")
print(f"Profit PREDICT RMSE: {predictions_rmse}")
print(f"{model_reg.summary()}")

# 假设分类任务：根据销售额的平均值进行分类
threshold = df['Sales'].mean()
y_test_class = (y_test > threshold).astype(int)
lr_predictions_class = (lr_predictions > threshold).astype(int)
svr_predictions_class = (svr_predictions > threshold).astype(int)
arima_predictions_class = (yhat > threshold).astype(int)
predictions_predictions_class = (predictions_reg > threshold).astype(int)
table_data = [
    ["Model", "Accuracy", "Recall", "Precision", "F1 Score", "MSE", "RMSE"],
    ['ARIMA', f"{accuracy_score(y_test_class, arima_predictions_class):.2f}",
     f"{recall_score(y_test_class, arima_predictions_class):.2f}",
     f"{precision_score(y_test_class, arima_predictions_class):.2f}",
     f"{f1_score(y_test_class, arima_predictions_class):.2f}",
     f"{arima_mse:.2f}", f"{arima_rmse:.2f}"]
]

print(table_data)
fig, ax = plt.subplots(figsize=(10, 7))
ax.axis('tight')
ax.axis('off')
the_table = ax.table(cellText=table_data, loc='center', cellLoc='center')
the_table.auto_set_font_size(False)
the_table.set_fontsize(14)
the_table.auto_set_column_width(
    col=list(range(len(["Model", "Accuracy", "Recall", "Precision", "F1 Score", "MSE", "RMSE"]))))

# 设置表格的列宽和行高为自适应
for (i, j), cell in the_table.get_celld().items():
    cell.set_text_props(fontproperties=plt.matplotlib.font_manager.FontProperties(weight='bold'))
plt.legend()
plt.show()

# 绘制线性回归模型的预测结果散点图
plt.figure(figsize=(10, 5))
plt.scatter(y_test, lr_predictions, label='Linear Regression Predictions')
plt.xlabel('Actual Sales')
plt.ylabel('Predicted Sales')
plt.title('Cost profit Linear Regression Predictions vs Actual Sales')
plt.legend()
# plt.savefig('linear_regression_predictions.png')  # 保存图像文件到当前目录
# plt.close()  # 关闭图像，释放资源
plt.show()

# 绘制支持向量机回归模型的预测结果散点图
plt.figure(figsize=(10, 5))
plt.scatter(y_test, svr_predictions, label='SVR Predictions')
plt.xlabel('Actual Sales')
plt.ylabel('Predicted Sales')
plt.title('Cost profit SVR Predictions vs Actual Sales')
plt.legend()
plt.show()

# 绘制均方误差对比图（使用条形图）
models = ['ARIMA MSE','ARIMA RMSE']
mses = [arima_mse,arima_rmse]
plt.figure(figsize=(10, 8))
plt.bar(models, mses, color='blue')
plt.xlabel('Model')
plt.ylabel('Mean Squared Error')
plt.title('Cost profit MSE and RMS Comparison between Models')
plt.legend()
plt.show()

# 绘制均方误差对比图（使用条形图）
models = ['ARIMA RMSE']
mses = [arima_rmse]
plt.figure(figsize=(10, 8))
plt.bar(models, mses, color='blue')
plt.xlabel('Model')
plt.ylabel('Mean Squared Error')
plt.title('Cost profit RMSE Comparison between Models')
plt.legend()
plt.show()

# 可视化预测结果与实际值的对比（仅展示线性回归模型的结果）散点图
plt.scatter(y_test, lr_predictions)
plt.xlabel('Actual Sales')
plt.ylabel('Predicted Sales')
plt.title('Cost profit Actual vs Predicted Sales (Linear Regression)')
plt.legend()
plt.show()

# 5. 可视化展示
# 展示时间序列预测结果（二维线图）
plt.figure(figsize=(10, 5))
plt.plot(y_test.index, y_test.values, label='Actual Profit')
plt.plot(y_test.index, yhat, label='Predicted Profit')
plt.title('Cost profit Actual vs Predicted Profit (ARIMA Model)')
plt.xlabel('Time Period')
plt.ylabel('Profit')
plt.legend()
plt.show()

# 展示多元回归分析中显著变量的系数（这里以热图的形式展示）
coefficients = model_reg.params
coefficients_df = pd.DataFrame(coefficients, columns=['Coefficient'])
coefficients_df['Variable'] = coefficients_df.index
plt.figure(figsize=(10, 8))
sns.set(font_scale=1.2)
sns.heatmap(coefficients_df[['Coefficient']].T, annot=True, fmt='.2f')
plt.title('Cost profit Regression Coefficients Heatmap')
plt.xlabel('Variables')
plt.ylabel('Coefficient')
plt.legend()
plt.show()


# 多元回归分析（这里以'Profit'利润作为因变量进行示例分析）
X = df[['Year', 'Month', 'Sales', 'Cogs', 'Margin', 'ActualandProfit', 'InventoryMargin']]
y = df['Profit']  # 假设CSV中有'Profit'利润这一列作为因变量
# train_test_split方法能够将数据集按照用户的需要指定划分为训练集和测试集/
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X, y, test_size=0.2, random_state=42)

# 数据标准化（此步骤对于可视化不是必需的，但保留以展示完整流程）
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 将训练集和测试集标签添加到原始DataFrame中，以便于可视化时区分
df['Dataset'] = 'Not Selected'
df.loc[X_train.index, 'Dataset'] = 'Train'
df.loc[X_test.index, 'Dataset'] = 'Test'
model_reg = sm.OLS(y_train_reg, X_train_reg).fit()
predictions_reg = model_reg.predict(X_test_reg)
# 输出回归分析结果，查看哪些变量对利润有显著影响
print(f"model_reg: {model_reg.summary()}")

# 展示多元回归分析中显著变量的系数（这里以热图的形式展示）
coefficients = model_reg.params
coefficients_df = pd.DataFrame(coefficients, columns=['Coefficient'])
coefficients_df['Variable'] = coefficients_df.index
plt.figure(figsize=(10, 8))
sns.set(font_scale=1.2)
sns.heatmap(coefficients_df[['Coefficient']].T, annot=True, fmt='.2f')
plt.title('Regression Coefficients Heatmap')
plt.xlabel('Variables')
plt.ylabel('Coefficient')
plt.show()